#include <iostream>

#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>

#include "GenericException.hpp"
#include "ConnectSocket.hpp"

ConnectSocket::ConnectSocket(const IP& destinationIP, unsigned int port) : destinationIP(destinationIP), port(port) {
}

ConnectSocket::ConnectSocket(const std::string& hostname, unsigned int port) : port(port) {
	struct hostent* resolved;
	resolved = gethostbyname(hostname.c_str());
	destinationIP.setTo(resolved->h_addr);
}

TCPConnection ConnectSocket::connect() {
	int sd = socket(PF_INET, SOCK_STREAM, 0);
	if (sd == -1) {
		GENERICSTRMEXCEPTION("Cannot create socket: " << strerror(errno));
	}

	struct sockaddr_in remote;
	remote.sin_family = AF_INET;
	memcpy(&remote.sin_addr.s_addr, destinationIP.getMemory(), 4);
	remote.sin_port = htons(port);
	if (::connect(sd, (struct sockaddr*)&remote, sizeof(struct sockaddr_in)) != 0) {
		GENERICSTRMEXCEPTION("Connect to " << destinationIP.getStr() << ":" << port << " failed: " << strerror(errno));
	}
	return TCPConnection(sd, destinationIP);
}

